package com.yupi.yupicturebackend.manager.websocket.ws;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.yupi.yupicturebackend.manager.websocket.PictureEditHandler;
import com.yupi.yupicturebackend.manager.websocket.model.PictureEditMessageTypeEnum;
import com.yupi.yupicturebackend.manager.websocket.model.PictureEditRequestMessage;
import com.yupi.yupicturebackend.manager.websocket.model.PictureEditResponseMessage;
import com.yupi.yupicturebackend.model.entity.User;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

@Component("ENTER_EDIT") // 关键：Bean名称=消息类型
public class EnterEditHandler extends BaseMessageHandler {

    @Override
    public void handle(PictureEditRequestMessage request, WebSocketSession session, User user, Long pictureId, PictureEditHandler context) throws Exception {
//        if (!context.getPictureEditingUsers().containsKey(pictureId)) {
//            context.getPictureEditingUsers().put(pictureId, user.getId());
//
//            PictureEditResponseMessage response = new PictureEditResponseMessage();
//            response.setType(PictureEditMessageTypeEnum.ENTER_EDIT.getValue());
//            response.setMessage(String.format("%s开始编辑图片", user.getUserName()));
//            response.setUser(userService.getUserVO(user));
//
//            broadcastToPicture(pictureId, response, null, context);
//        }


        // 原子操作：如果key不存在则put，返回null；否则返回已存在的value
        // putIfAbsent 是原子操作，确保检查和插入的整个过程不会被其他线程打断。
        Long previousEditor =  context.getPictureEditingUsers().putIfAbsent(pictureId, user.getId());
        // 如果previousEditor为null，则表示成功获取编辑权限(前面没有其他用户在占用)，否则表示图片已被其他用户编辑
        if (previousEditor == null) {
            // 成功获取编辑权限
            PictureEditResponseMessage response = new PictureEditResponseMessage();
            response.setType(PictureEditMessageTypeEnum.ENTER_EDIT.getValue());
            response.setMessage(String.format("%s开始编辑图片", user.getUserName()));
            response.setUser(userService.getUserVO(user));
//            // 广播给同一张图片的用户
//            //因为只是单纯的消息通知 ，不会造成像编辑的多次操作的影响 所以可以给自己也发广播
//            //效果就是当前用户也可以在页面里看到自己  xxx开始了编辑
            broadcastToPicture(pictureId, response, null, context);
        } else {
            // 图片已被其他用户编辑
            /**
             * 直接向当前 WebSocket 连接对应的客户端发送消息，但不会自动广播给其他客户端。这是 WebSocket 的单点消息发送机制
             * 如果想要广播 那就是像broadcastToPicture里面一样 把每个session会话取出来 进行发送消息
             */
            PictureEditResponseMessage response = new PictureEditResponseMessage();
            response.setType(PictureEditMessageTypeEnum.INFO.getValue());
            User userInfo = userService.getById(previousEditor);
            response.setMessage(String.format("当前图片正在被%s编辑", userInfo.getUserName()));
            response.setUser(userService.getUserVO(userInfo));

            // 创建 ObjectMapper
            ObjectMapper objectMapper = new ObjectMapper();
            // 配置序列化：将 Long 类型转为 String，解决丢失精度问题
            SimpleModule module = new SimpleModule();
            module.addSerializer(Long.class, ToStringSerializer.instance);
            module.addSerializer(Long.TYPE, ToStringSerializer.instance); // 支持 long 基本类型
            // 注册自定义序列化器模块
            objectMapper.registerModule(module);

            // 序列化为 JSON 字符串
            String message = objectMapper.writeValueAsString(response);
            TextMessage textMessage = new TextMessage(message);
            session.sendMessage(textMessage);
        }
    }
}